package com.liuwenlin.zookeeper.zkclient.config;

import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.util.concurrent.CountDownLatch;

/**
 * 此类用于测试zookeeper的reactive的异步编程模式
 * @author liuwenlin
 * @version v1.0
 * @date 2021/2/1 16:23
 */
public class WatchCallBack implements Watcher,AsyncCallback.StatCallback, AsyncCallback.DataCallback{

    ZooKeeper zk;

    MyConf conf;

    /**
     * 门闩
     */
    CountDownLatch cc = new CountDownLatch(1);

    public ZooKeeper getZk() {
        return zk;
    }

    public void setZk(ZooKeeper zk) {
        this.zk = zk;
    }

    public MyConf getConf() {
        return conf;
    }

    public void setConf(MyConf conf) {
        this.conf = conf;
    }

    public CountDownLatch getCc() {
        return cc;
    }

    public void setCc(CountDownLatch cc) {
        this.cc = cc;
    }

    /**
     * 利用回调机制,阻塞调用线程
     */
    public void await(){
        //检查业务服务节点是否存在
        zk.exists("/AppConf", this, this, "abc");
        try {
            cc.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 监听到节点有数据变动,就回调此方法
     * @param rc
     * @param path
     * @param ctx
     * @param data
     * @param stat
     */
    @Override
    public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
        System.out.println("Get data callback method >>>");
        if(data != null){
            String result = new String(data);
            conf.setConf(result);
            cc.countDown();
        }
    }

    @Override
    public void processResult(int rc, String path, Object ctx, Stat stat) {
        System.out.println("Stat callback method >>>");
        if(stat != null){
            zk.getData("/AppConf", this, this, "hello");
        }
    }

    @Override
    public void process(WatchedEvent event) {
        switch (event.getType()) {
            case None:
                break;
            case NodeCreated:
                System.out.println("NodeCreated event handler...");
                zk.getData("/AppConf", this, this, "hello");
                break;
            case NodeDeleted:
                System.out.println("NodeDeleted event handler...");
                //容忍性,看你的业务是否容忍节点的删除
                conf.setConf("");
                cc = new CountDownLatch(1);
                break;
            case NodeDataChanged:
                System.out.println("NodeDataChanged event handler...");
                zk.getData("/AppConf", this, this, "hello");
                break;
            case NodeChildrenChanged:
                break;
            case DataWatchRemoved:
                break;
            case ChildWatchRemoved:
                break;
            case PersistentWatchRemoved:
                break;
            default: System.out.println("default event handler...");
        }
    }
}
